<template>
  <div class="lyric-box">
    <!-- 这个标签负责做背景 -->
    <div class="bg-1"></div>
    <div class="bg" :style="`background-image:url(${picUrl})`"></div>
    <!-- 这个标签负责做内容 -->
    <div class="content" @touchmove="touchMoveFn" @touchend="touchEndFn">
      <!-- 头部 -->
      <header>
        <span class="i-left" @click="goBack"></span>
      </header>
      <!-- 封面/歌曲信息 -->
      <section :class="isShowLyric == true ? 'current' : ''">
        <div class="img-box">
          <img :src="picUrl" @click="isShowLyric = !isShowLyric" alt="" />
        </div>
        <div class="info-box">
          <div class="left">
            <div>{{ name }}</div>
            <p>{{ text }}</p>
          </div>
          <div class="right">
            <span v-if="songs[key]" @click="collectionFn(id)" :class="['icon',songs[key].isCollection == true ?'active':'']"></span>
          </div>
        </div>
      </section>
      <section v-if="isShowLyric">
        <!-- 歌词列表 -->
        <div class="geci-box">
          <!-- 滚动歌词的做法 -->
          <ul
            v-if="lyrics.length != 0"
            :style="`transform: translateY(-${
              index * 40
            }px); transition: transform .2s`"
          >
            <li
              v-for="(item, j) in lyrics"
              :key="item.id"
              :class="j == index ? 'active' : ''"
            >
              {{ item.text }}
            </li>
          </ul>
        </div>
      </section>
      <section>
        <div class="jdt-box">
          <ul ref="ul">
            <li :style="`width:${w}px;`">
              <span :style="`left:${w}px;`" @touchstart="touchStartFn"> </span>
            </li>
          </ul>

          <div class="time" style="color: #000">
            <span>{{ currentTime | formatime }}</span>
            <span>{{ duration | formatime }}</span>
          </div>
        </div>
      </section>
      <section>
        <div class="btn-box">
          <div class="btn-prev" @click="audioPrevFn"><i></i></div>
          <!-- audioControlFn 控制播放或暂停 -->
          <div class="btn-pause" @click="audioControlFn"><i></i></div>
          <div class="btn-next" @click="audioNextFn"><i></i></div>
        </div>
      </section>
    </div>
  </div>
</template>
  
<script>
// 导入接口
import { recommendSongsFn, newsongFn, getLyric } from "@/api/index";
// 匹配歌词的正则表达式
let exp = /\[(\d{2,3}):(\d{2,3})\.(\d{2,3})\](.{0,})/;

export default {
  data() {
    return {
      picUrl: "", // 封面
      name: "", //歌曲名称
      text: "", // 歌手/乐队名称
      isShowLyric: true, // 是否显示歌词
      songs: [], // 歌曲列表
      key: 0, // 歌曲索引
      lyrics: [], // 歌词数组
      duration: 0, // 音频总时长
      currentTime: 0, //音频当前播放时长
      totalWidth: 0, // 进度条总宽度
      w: 0, // 进度条的播放宽度
      index: 0, // 歌词索引值
      id: "", //音乐id
      type: "", // 音乐类型
      isStart: "", // 判断是否按下进度条小球
      offsetLeft: 0, //
      isPlay: true, //判断音频是否播放
    };
  },

  // 过滤器
  filters: {
    formatime(seconds) {
      let m = Math.floor(seconds / 60);
      let s = Math.floor(seconds % 60);
      m = m < 10 ? "0" + m : m;
      s = s < 10 ? "0" + s : s;
      return `${m}:${s}`;
    },
  },

  watch: {
    $route: {
      deep: true,
      immediate: true,
      async handler(newRoute) {
        // console.log('-->',newRoute)
        // 解构赋值
        let { id, type } = newRoute.query;
        if (id) {
          //获取歌曲列表
          if (type == "recommand") {
            await this.recommendSongsFunc(id);
          } else if (type == "newsong") {
            await this.newsongFunc(id);
          }

          // 循环songs数组,获取歌曲的索引
          // this.songs.forEach(()=>{})
          for (var key = 0; key < this.songs.length; key++) {
            if (this.songs[key].id == id) {
              //匹配歌曲的索引
              this.key = key;
              break;
            }
          }
          //检测一遍有哪些歌曲是被收藏的了
          let songs_str = localStorage.getItem('_SONGS');
          let _USER = localStorage.getItem('_USER');
          if(songs_str){
              let arr = JSON.parse(songs_str);
              let user = JSON.parse(_USER)
              for(let i = 0 ; i  < arr.length ; i ++){
                 for(let j = 0 ; j < this.songs.length ; j ++){
                    if(arr[i].id == this.songs[j].id && arr[i].user_id == user['id']) {
                      this.songs[j].isCollection = true;
                    }
                 }
              }
          }

          //获取歌词
          this.getLyricFunc(id, type);
          this.id = id;
          this.type = type;
        }
      },
    },
    // 观察音频播放
    currentTime(value) {
      // console.log({value, t: this.lyrics[0].times})
      // 在解析歌词的时候，每一行歌词都有时间...
      for (var i = 0; i < this.lyrics.length - 1; i++) {
        // 根据播放的时间匹配歌词
        if (value >= this.lyrics[i].times && value < this.lyrics[i + 1].times) {
          this.index = i;
          break;
        }
      }
    },
  },

  methods: {
    // 收藏歌曲
    collectionFn(id){
       //首先从本地空间获取数据
       let songs_str = localStorage.getItem('_SONGS');
       let _TOKEN = localStorage.getItem('_TOKEN');
       let user_str = localStorage.getItem('_USER');
       //判断是否存在token
       if(_TOKEN == null) {
          alert('您还没登录');
          return ;
       }
       // 把符合id条件的歌曲储存在收藏列表中
       let user = JSON.parse(user_str)
       let song = {};
       //根据id从音乐列表中获取数据
       this.songs.forEach((item,index)=> {
          //整合需要收藏的数据
          if(item.id == id){
            this.songs[index].isCollection = !this.songs[index].isCollection;
            // 取出根id匹配的歌曲
            song = item;
            //添加用户字段
            song.user_id = user['id'];
            this.key = index;
          }
       })
       //  判断本地是否存在数据
       if(songs_str == null) {
          //没有收藏
          let songs = [];
          songs.push(song);
          let str2 = JSON.stringify(songs);
          localStorage.setItem('_SONGS',str2)
       }
       else {
          //已经有收藏
          let songs =  JSON.parse(songs_str);
          let index = 0;
          songs.forEach((item,index)=>{
             //取出跟id匹配的本地歌曲的下标
              if(item.id == song.id){
                index = index;
              }
          })
          // 判断用户是否点击 (并确认是否需要收藏)
          if(song.isCollection){
            // 是 添加到本地
            songs.push(song);
          }
          else {
            // 否 从本地移除
            songs.splice(index,1);
          }
          let str2 = JSON.stringify(songs);
          localStorage.setItem('_SONGS',str2);
       }
    },
    // 切换歌词
    audioPrevFn() {
      // console.log("上一首",this.key, this.songs)
      let key = this.key;
      key--;
      if (key < 0) {
        key = 0;
        alert("没有上一首歌曲了.");
      }
      if (this.songs[key]) {
        this.id = this.songs[key].id;
        this.picUrl = this.songs[key].artist.picUrl;
        this.name = this.songs[key].name;
        this.text = this.songs[key].text;
        this.key = key;

        //  获取歌词
        this.getLyricFunc(this.id);
        // 发送id给其他组件使用
        this.bridge.$emit("audio-id", {
          id: this.id,
        });
      }
    },
    audioNextFn() {
      // console.log("下一首",this.key, this.songs)
      let key = this.key;
      key++;
      if (key > this.songs.length - 1) {
        key = this.songs.length - 1;
        alert("没有最后一首歌曲了.");
      }
      if (this.songs[key]) {
        this.id = this.songs[key].id;
        this.picUrl = this.songs[key].artist.picUrl;
        this.name = this.songs[key].name;
        this.text = this.songs[key].text;
        this.key = key;
        //  获取歌词
        this.getLyricFunc(this.id);

        this.bridge.$emit("audio-id", {
          id: this.id,
        });
      }
    },
    // 控制音频播放暂停
    audioControlFn() {
      this.isPlay = !this.isPlay;
      // 此处涉及组件传值
      this.bridge.$emit("audio-control", {
        isPlay: this.isPlay,
      });
    },
    // 控制进度条滑动
    touchStartFn() {
      this.isStart = true;
    },
    touchMoveFn(event) {
      if (this.isStart) {
        let x = event.touches[0].pageX;
        // console.log("总宽度:", x);
        // console.log("距离容器X:", this.offsetLeft);
        this.w = x - this.offsetLeft;
        //计算比例
        let demo = this.w / this.totalWidth;

        // 利用比例和总时长,计算当前播放时长
        this.currentTime = demo * this.duration;

        // 此处涉及组件传值
        this.bridge.$emit("touch-current-time", {
          currentTime: this.currentTime,
        });
      }
    },
    touchEndFn() {
      this.isStart = false;
    },
    // 跳转上一个页面（返回歌曲列表页面）
    goBack() {
      // 跳转页面API
      // this.$router.back();
      this.$router.push({
        path: "/home/list",
        query: {
          id: this.id,
          type: this.type,
          played: false,
        },
      });
    },
    // 获取每日推荐歌曲
    async recommendSongsFunc(rid) {
      await recommendSongsFn().then((content) => {
        let {
          code,
          data: { dailySongs },
        } = content;
        if (code == 200) {
          let arr = dailySongs.map((item) => {
            let id = item.id;
            let title = "推荐歌曲";
            let artist = { picUrl: item.al.picUrl };
            let name = item.name;
            let text = item.al.name;
            let type = "recommand";
            return {
              id,
              title,
              artist,
              name,
              type,
              text,
              isCollection: false
            };
          });
          // 控制列表对应的选项样式高亮
          // 进行赋值
          let newArr = arr.map((item) => {
            // console.log(item.id , rid , item.id == rid)
            if (item.id == rid) {
              // console.log("---->", item.artist);
              item.isPlay = true;
              item.isCollection = false;
              this.picUrl = item.artist.picUrl;
              this.name = item.name;
              this.text = item.text;
            }
            return item;
          });
          this.songs = newArr;
          // console.log("xx:",this.songs,this.key)
        }
      });
    },
    // 获取新音乐
    async newsongFunc(rid) {
      // console.log("test  3333",rid);
      await newsongFn().then((content) => {
        let { code, result } = content;
        if (code == 200) {
          // console.log("10.0",result)
          let arr = result.map((item) => {
            let id = item.id;

            let title = "最新音乐";
            let artist = { picUrl: item.picUrl };
            let name = item.name;
            let text = item.song.name;
            let type = "newsong";
            return {
              id,
              title,
              artist,
              name,
              type,
              text,
              isCollection: false
            };
          });
          // 控制列表对应的选项样式高亮
          // 进行赋值
          let newArr = arr.map((item) => {
            // console.log(item.id , rid , item.id == rid)
            if (item.id == rid) {
              // console.log("test  5555", item.artist);
              item.isPlay = true;
              item.isCollection = false;
              this.picUrl = item.artist.picUrl;
              this.name = item.name;
              this.text = item.text;
            }
            return item;
          });
          this.songs = newArr;
          // console.log("xx:",this.songs)
        }
      });
    },
    // 获取歌词
    async getLyricFunc(id) {
      // 获取歌词信息
      await getLyric({ id }).then((content) => {
        // console.log("歌词数据:", content);
        let {
          code,
          lrc: { lyric },
        } = content;
        if (code == 200) {
          // console.log("歌词:", lyric);
          // 根据 /n 换行符 把字符串切割成数组

          //没有歌词 终止代码
          if (lyric.includes("无\n\n")) {
            return false;
          }

          let arr = lyric.split("\n");
          // console.log(arr);
          // 删除数组中最后一个空字符串
          arr.pop();

          let newArr = arr.map((lyric, index) => {
            // 解剖符合正则表达式的歌词
            if (exp.test(lyric)) {
              let arg = exp.exec(lyric);
              let m = arg[1];
              let s = arg[2];
              let ms = arg[3];
              // 转number类型
              m = Number(m);
              s = Number(s);
              ms = Number(ms);
              // 计算秒数
              let times = m * 60 + s + ms / 1000;

              // 歌词文本
              let text = arg[4];

              return {
                times,
                text,
                id: Math.random().toString().slice(2),
              };
            }
          });

          // console.log(newArr);
          // 赋值
          this.lyrics = newArr;
        }
      });
    },
  },

  created() {
    // 观察音频当前播放的时间
    this.bridge.$on("send-current-time", (option) => {
      // console.log("option->", option);
      this.currentTime = option.currentTime;
      this.duration = option.duration;
      let demo = this.currentTime / this.duration;
      this.w = demo * this.totalWidth;
    });
  },

  // 获取ul标签的宽度
  mounted() {
    this.$nextTick(() => {
      if (this.$refs["ul"]) {
        let dom = this.$refs["ul"];
        this.totalWidth = parseFloat(getComputedStyle(dom)["width"]);
        this.offsetLeft = dom.offsetLeft;
        // console.log("宽度:", this.totalWidth);
      }
    });
  },
};
</script>
  
<style lang="less">
@import "@/static/less/variable.less";

.lyric-box {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2000;
  width: 100%;
  height: 100%;
  // padding: @pad;
  box-sizing: border-box;
  overflow: hidden;
  header {
    width: 100%;
    height: 64px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .i-left {
      display: block;
      width: 24px;
      height: 24px;
      background-image: url(@/static/images/i-arrow-left.png);
      background-size: cover;
    }
  }
  section.current {
    width: 100%;
    display: flex;
    justify-content: flex-start;
    .img-box {
      img {
        width: 80px;
        border-radius: 5px;
        box-shadow: 0px 0px 5px #fff;
      }
    }
    .info-box {
      width: calc(100% - 80px);
      padding-left: 15px;
      margin-top: 0px;
      box-sizing: border-box;
      .right {
        .icon {
          margin-right: 0px;
        }
        .icon.active {
          background-image: url(../../static/images/i-like-on.png);
        }
      }
    }
  }
  section {
    padding: 10px 15px;
    .img-box {
      img {
        width: 100%;
        border-radius: 10px;
        box-shadow: 0px 0px 5px #fff;
        // transition: width .2s;
      }
    }

    .info-box {
      width: 100%;
      display: flex;
      font-size: 16px;
      justify-content: space-between;
      align-items: center;
      // transition: width .2s;
      margin-top: 10px;
      .left {
        color: #fff;
        div {
          font-size: 17px;
        }
        p {
          font-size: 14px;
          padding-top: 5px;
        }
      }

      .right {
        .icon {
          width: 24px;
          height: 24px;
          background-image: url(../../static/images/i-like.png);
          background-size: cover;
          display: inline-block;
        }
        .icon.active {
          background-image: url(../../static/images/i-like-on.png);
        }
      }
    }

    .jdt-box {
      width: 100%;
      padding: 15px 0;

      ul {
        height: 4px;
        width: 100%;
        background-color: rgba(255, 255, 255, 0.45);
        position: relative;

        li {
          width: 0px;
          height: 4px;
          background-color: #fff;
        }

        span {
          position: absolute;
          top: -5px;
          left: 0px;
          width: 14px;
          height: 14px;
          background-color: #fff;
          border-radius: 50%;
        }
      }

      .time {
        width: 100%;
        display: flex;
        justify-content: space-between;
        color: #fff;
        font-size: 14px;
        margin-top: 10px;
      }
    }

    .btn-box {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-bottom: 100px;

      [class^="btn"] {
        width: 30px;
        height: 30px;
        margin: 0 20px;
      }

      .btn-prev {
        background-image: url(@/static/images/i-prev.png);
      }

      .btn-pause {
        background-image: url(@/static/images/i-pause.png);
        transform: scale(1.5);
      }

      .btn-next {
        background-image: url(@/static/images/i-next.png);
      }
    }

    .geci-box {
      width: 100%;
      height: 280px;
      overflow: hidden;
      ul {
        width: 100%;
        transition: transform 0.5s;
        transform: translateY(0px);
        font-size: 18px;
        margin-top: 40px;
        li {
          color: #ccc;
          text-align: left;
          line-height: 1.7;
          margin-bottom: 10px;
          transition: color 0.2s;
          text-align: center;
          transition: all 0.2s;
        }
        .active {
          color: @color;
          font-size: 24px;
        }
      }
    }
  }

  .bg-1 {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    background-color: #fff;
  }

  .bg {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    background-color: #fff;
    // 设置背景模糊度
    background-image: url(https://p1.music.126.net/PzAdCVYmLkKcEY5hE1GfpA==/109951163846016953.jpg);
    background-size: 100% 100%;
    filter: blur(50px);
    background-repeat: no-repeat;
  }

  .content {
    width: 100%;
    height: 100%;
    // 因为父元素设置了固定定位  所以子元素设置可滚动
    overflow-y: scroll;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    padding: @pad;
    box-sizing: border-box;
  }

  ::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
  }
}
</style>